﻿using System;
using Framework.MVC;
using Log.Model;
using Identity.Model;
using Identity.IService.Entry;
using Billing.Model;
using Billing.IService.Entry;
using Account.Model;
using Account.IService.Entry;
using Framework.MVVM.Model;
using Log.IService;
using Log.Service;
using Common.IService;
using Common.Service;
using Identity.IService;
using Identity.Service;
using Billing.IService;
using Billing.Service;
using Account.IService;
using Account.Service;
using Account.Model.Behavior;
using Config.Model;
using Framework.Extention.Billing;
using System.Collections.Generic;
using Framework.Common.Entry;
using Config.IService;
using Config.Service;


namespace Recharge.Models
{
    [ServiceAttribute(typeof(IConfigService), typeof(ConfigService), "Instance")]
    [ServiceAttribute(typeof(IAccountService), typeof(AccountService), "Instance")]
    [ServiceAttribute(typeof(IRechargeOrderService), typeof(RechargeOrderService), "Instance")]
    [ServiceAttribute(typeof(IIdentityService), typeof(IdentityService), "Instance")]
    [ServiceAttribute(typeof(ILogService), typeof(LogService), "Instance")]
    [ServiceAttribute(typeof(ICodeService), typeof(CodeService), "Instance")]
    public class ShowReChargeOrderModel : AsyncModelBase, IWriteLog, IValidateIdentity, IGetRechargeOrder, IGetAccountByCode, IGetConfig<IDictionary<string, KeyValueEntry<string, double>>>, IGetConfig<IDictionary<string, KeyValueEntry<string, string>>>, IGetConfig<IBilling>
    {
        #region Field
        
        private const string m_empty_identity = "showcge00";
        private const string m_error_identity = "showcge01";
        private const string m_complete_identity = "showcge02";
        private const string m_error_rechargeOrder_format = "showcge03";
        private const string m_error_rechargeOrder = "showcge04";
        private const string m_error_rechargeOrder_not_owner = "showcge05";
        private const string m_complete_rechargeOrder = "showcge06";
        private const string m_error_revicer_empty = "showcge07";
        private const string m_error_revicer = "showcge08";
        private const string m_complete_revicer = "showcge09";
        private const string m_error_config_source = "showcge10";
        private const string m_complete_config_source = "showcge11";
        private const string m_error_type = "showcge12";
        private const string m_complete_type = "showcge13";
        private const string m_error_config_billing = "showcge14";
        private const string m_complete_config_billing = "showcge15";

        private const string m_resource_user = "u000";

        private const string m_order = "order";
        private const string m_account = "account";

        private const string m_exchange = "exchange";

        private const string m_split = ";";

        private const string m_type_config = "data:recharge:type";
        private const string m_source_config = "data:recharge:source";

        private IdentityEntry m_identity;

        #endregion Field

        #region AsyncModelBase

        protected override void OnInit(Type type)
        {
            OnBeginRequest();
            this.ValidateIdentity(m_resource_user,m_empty_identity, m_error_identity, m_complete_identity);
        }

        #endregion AsyncModelBase

        #region Write Log

        public void OnWriteLogComplete(string eventCode)
        {
            OnEndRequest();
        }

        public void OnWriteLogError(string eventCode)
        {
            OnEndRequest();
        }

        #endregion Write Log

        #region IValidateIdentity

        public string IdentityCode { get; set; }
        public string Source { get; set; }

        public void OnValidateIdentityComplete(string key, IdentityEntry entry)
        {
            OnBeginRequest();
            this.Log(key, entry);
            m_identity = entry;
            this.GetRechargeOrder(m_error_rechargeOrder_format, m_error_rechargeOrder, m_complete_rechargeOrder);
        }

        public void OnValidateIdentityError(string key)
        {
            this.Log(key, new IdentityEntry { code = IdentityCode, source = Source, resource = m_resource_user });
        }

        #endregion IValidateIdentity

        #region IGetRechargeOrder

        public string RechargeOrderCode { get; set; }

        public void OnGetRechargeOrderComplete(string key, RechargeOrderEntry entry)
        {
            if (string.Equals(m_identity.value, entry.owner) || string.Equals(m_identity.value, entry.receiver))
            {
                OnBeginRequest();
                OnComplete(m_order,entry);
                this.Log(key, entry);

                OnBeginRequest();
                AccountCode = entry.receiver;
                this.GetAccount(m_error_revicer_empty, m_error_revicer, m_complete_revicer);

                m_type = entry.type;
                m_amount = entry.amount;
                m_source = entry.sourceCode;
                ConfigName = m_source_config;
                this.GetConfig<IDictionary<string, KeyValueEntry<string, double>>>(m_error_config_source, m_complete_config_source);
            }
            else
                this.Log(m_error_rechargeOrder_not_owner, Source + m_split + entry.code);
        }

        public void OnGetRechargeOrderError(string key)
        {
            this.Log(key, Source + m_split + RechargeOrderCode);
        }

        #endregion IGetRechargeOrder

        #region IGetAccountByCode

        public string AccountCode { get; set; }

        public void OnGetAccountByCodeComplete(string key, AccountEntry entry)
        {
            OnComplete(m_account, entry);
            this.Log(key, entry);
        }

        public void OnGetAccountByCodeError(string key)
        {
            this.Log(key, Source + m_split + AccountCode);
        }

        #endregion IGetAccountByCode

        #region IGetConfig Billing Source

        private string m_source = string.Empty;

        public void OnGetConfigComplete(string key, IDictionary<string, KeyValueEntry<string, double>> entry)
        {
            if (entry.ContainsKey(m_source))
            {
                OnBeginRequest();
                OnComplete(m_exchange, entry[m_source].value);
                m_subject = entry[m_source].key;
                ConfigName = m_type_config;
                this.GetConfig<IDictionary<string, KeyValueEntry<string, string>>>(m_error_type, m_complete_type);
            }

            this.Log(key, Source + m_split + RechargeOrderCode);
        }

        #endregion IGetConfig Billing Source

        #region IGetConfig Billing Type

        private string m_type = string.Empty;

        public void OnGetConfigComplete(string key, IDictionary<string, KeyValueEntry<string, string>> entry)
        {
            if (entry.ContainsKey(m_type))
            {
                OnBeginRequest();
                ConfigName = entry[m_type].key;
                m_billing_type = entry[m_type].value;
                this.GetConfig<IBilling>(m_error_config_billing, m_complete_config_billing);
            }
            this.Log(key, Source + m_split + RechargeOrderCode);

        }

        #endregion IGetConfig Billing Type

        #region IGetConfig Billing

        private int m_amount = 0;
        private string m_subject = string.Empty;
        private string m_billing_type = string.Empty;

        private const string m_order_name = "order";
        private const string m_amount_name = "amount";
        private const string m_subject_name = "subject";
        private const string m_type_name = "type";
        private const string m_input_type_name = "input_type";

        private const string m_billing = "billing";

        public string ConfigName { get; set; }

        public void OnGetConfigComplete(string key, IBilling billing)
        {
            var entry = billing.InitParams(
                new KeyValueEntry<string, object> { key = m_order_name,value=RechargeOrderCode },
                new KeyValueEntry<string, object> { key = m_amount_name,value=m_amount },
                new KeyValueEntry<string, object> { key = m_subject_name, value = m_subject },
                new KeyValueEntry<string, object> { key = m_input_type_name, value = m_billing_type },
                new KeyValueEntry<string, object> { key = m_type_name, value = m_type }
                );
            OnComplete(m_billing,entry);
            this.Log(key, Source + m_split + RechargeOrderCode);
        }

        public void OnGetConfigError(string key)
        {
            this.Log(key, Source + m_split + RechargeOrderCode);
        }

        #endregion IGetConfig Billing
    }
}